package com.xjt.wx_admin.service.impl;

import cn.hutool.crypto.digest.MD5;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjt.wx_admin.constant.WxConstant;
import com.xjt.wx_admin.entity.User;
import com.xjt.wx_admin.entity.UserFriend;
import com.xjt.wx_admin.entity.dto.EditRemarkParam;
import com.xjt.wx_admin.entity.dto.LoginParam;
import com.xjt.wx_admin.entity.dto.UserDto;
import com.xjt.wx_admin.mapper.UserMapper;
import com.xjt.wx_admin.security.LoginUser;
import com.xjt.wx_admin.security.login.AuthenticationToken;
import com.xjt.wx_admin.service.UserFriendService;
import com.xjt.wx_admin.service.UserService;
import com.xjt.wx_admin.util.BeanUtil;
import com.xjt.wx_admin.util.RedisUtil;
import com.xjt.wx_admin.util.SecurityUtils;
import com.xjt.wx_admin.util.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Xujt
 * @since 2023-03-22 11:33:28
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    UserFriendService userFriendService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public User getUser(String userName) {
        User user = getByUserName(userName);
        if (user == null){
            user = new User(userName);
            save(user);
        }else {
            user.setOnline(1);
            updateById(user);
        }
        return user;
    }

    @Override
    public User getUser(String userName,String password) {
        User user = getByUserName(userName);
        if (user == null){
            user = new User(userName,password);
            save(user);
        }else {
            if (MD5.create().digestHex(password, StandardCharsets.UTF_8).equals(user.getPassword())) {
                user.setOnline(1);
                updateById(user);
            }else {
                return null;
            }
        }
        return user;
    }


    @Override
    public User getByUserName(String userName) {
        return getOne(Wrappers.<User>lambdaQuery()
                .eq(User::getUserName, userName)
        );
    }


    @Override
    public List<UserDto> queryUserList(String name) {
        List<User> users = baseMapper.queryUserList(SecurityUtils.getUserId(),name);
        List<UserDto> userDtos = new ArrayList<>();
        for (User user : users) {
            UserDto userDto = BeanUtil.deepCopy(user, UserDto.class);
            userDtos.add(userDto);
        }
        return userDtos;
    }


    @Override
    public List<UserDto> searchUserList(String name) {
        List<User> users = baseMapper.searchUserList(SecurityUtils.getUserId(),name);
        List<UserDto> userDtos = new ArrayList<>();
        for (User user : users) {
            UserDto userDto = BeanUtil.deepCopy(user, UserDto.class);
            userDtos.add(userDto);
        }
        return userDtos;
    }


    @Override
    public R<String> login(LoginParam loginParam) {
        AuthenticationToken authenticationToken = new AuthenticationToken(loginParam);
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)){
         throw new RuntimeException("登录失败");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String token = TokenUtils.token(loginUser.getUsername(),loginUser.getUser().getId());
        Set<String> keys = redisUtil.keys("login:" + loginUser.getUsername() + ":*");
        if (!CollectionUtils.isEmpty(keys)){
            redisUtil.del(keys);
        }
        redisUtil.setex("login:"+loginUser.getUsername()+":"+token, JSONObject.toJSONString(loginUser),60*60*24*3);
        return R.ok(token);
    }

    @Override
    public R editRemark(EditRemarkParam editRemarkParam) {
        UserFriend userFriend = userFriendService.getOne(Wrappers.<UserFriend>lambdaQuery()
                .eq(UserFriend::getUserId, SecurityUtils.getUserId())
                .eq(UserFriend::getFriendId, editRemarkParam.getFriendId())
        );
        if (userFriend==null){
            return R.failed("当前用户不是你的好友");
        }else {
            userFriend.setRemark(editRemarkParam.getRemark());
            return R.ok(userFriendService.updateById(userFriend));
        }
    }

    String createToken(String userName){
        Map<String, Object> map = new HashMap<>();
        map.put("userName",userName);
        return JWTUtil.createToken(map, WxConstant.jwtSigner);
    }
}
